from base.base_tools import Mymongo
import requests
from config import get_token
import sys
from loguru import logger
sys.path.append("..")
# 把数据插入到mongodb中
from pandas import DataFrame
from concurrent.futures import ThreadPoolExecutor, as_completed
from base.base_tools import get_datetime_x_days_ago


def chunk(lst, size):
    from math import ceil
    return list(
        map(lambda x: lst[x * size:x * size + size],
            list(range(0, ceil(len(lst) / size)))))


def singleton(cls):
    instances = {}

    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return get_instance


# @singleton
class Base():

    def __init__(self, account) -> None:
        '''
        account: 主账号的账户id
        '''

        self.token = get_token(account)
        self.headers = {
            "Access-Token": self.token,
            "Content-Type": "application/json",
        }
        self.account = account
        
    
    def add_campaign(self,ad_type = 0):
        url = "https://ad.e.kuaishou.com/rest/openapi/gw/dsp/campaign/create"
        data = {
            "advertiser_id": self.advertiser_id,
            "campaign_name":f"{'信息流' if ad_type == 0 else '搜索'}_{get_datetime_x_days_ago(0)}",
            "type":2,  #营销目标类型
            "ad_type": ad_type
        }
        data =  requests.post(url,headers=self.headers,json=data).json()
        return data

    def get_quota_info(self,advertiser_id):
        url =  "https://ad.e.kuaishou.com/rest/openapi/gw/dsp/quota/info"
        data = {
            "advertiser_id":advertiser_id
        }
        response = requests.post(url,headers=self.headers,json=data)
        return response.json()

    def add_search_word(self,campaign_id,unit_id,kws,match_type=2):
        # 搜索关键词的批量创建
        url = "https://ad.e.kuaishou.com/rest/openapi/v2/word_info/create"
        word_infos = []
        for kw in kws:
            item = {
                "word":kw,
                "match_type": match_type
            }
            word_infos.append(item)
        data = {
            "advertiser_id":self.advertiser_id,
            "campaign_id":campaign_id,
            "unit_id":unit_id,
            "word_infos":word_infos
        }

        data  = requests.post(url,headers=self.headers,json=data)
        return data.json()




    def get_video_list(self, advertiser_id, page, page_size=200,outer_loop_native=1):
        url = "https://ad.e.kuaishou.com/rest/openapi/v1/file/ad/video/list"
        data = {
            "advertiser_id": advertiser_id,
            "page": page,
            "page_size": page_size,
            # "outer_loop_native":outer_loop_native
        }
        response = requests.post(url, headers=self.headers, json=data)
        return response.json()



    def get_video_relate_creatives_data(self, advertiser_id, photo_ids):
        def fetch_data(ids):
            logger.info(f"正在采集{ids}")
            data = {
                "advertiser_id": advertiser_id,
                "photo_ids": ids
            }
            response = requests.post(url, headers=self.headers, json=data)
            return response.json()["data"]["related_creatives"]

        url = "https://ad.e.kuaishou.com/rest/openapi/v1/file/ad/video/relate/creatives"
        data_list = []

        # 使用 ThreadPoolExecutor 管理线程
        with ThreadPoolExecutor() as executor:
            # 创建 Future 对象列表
            futures = [executor.submit(fetch_data, ids) for ids in chunk(photo_ids, 20)]
            
            # 收集每个线程的结果
            for future in as_completed(futures):
                data_list.extend(future.result())

        return data_list

    def get_video_relate_creatives_data_num(self, advertiser_id, photo_ids):
        json_data_list = self.get_video_relate_creatives_data(advertiser_id, photo_ids)        
        list_dict_data = []
        for data in json_data_list:
            item = {
                "advertiser_id":advertiser_id,
                "photo_id": data["photo_id"],
                "related_creatives_count": data["advanced_creative_count"]
            }
            list_dict_data.append(item)
        return list_dict_data


    def update_all_get_video_list(self, advertiser_id, page_size=200, debug=False):
        list_data = []
        data = self.get_video_list(
            advertiser_id=advertiser_id, page=1, page_size=page_size)
        total_count = data["data"]["total_count"]
        list_data.extend(data["data"]["details"])
        logger.info(f"第1页采集完成")
        if debug:
            list_data = [{**item, "max_video_count": 0,
                          "advertiser_id": advertiser_id} for item in list_data]
            return list_data
        if total_count > 1:
            total_page = (total_count // page_size) + 1  # 计算总的分页数
            # 开始循环采集各个网页
            # 遍历所有的数据
            for page in range(2, total_page+1):
                data = self.get_video_list(
                    advertiser_id=advertiser_id, page=page, page_size=page_size)
                list_data.extend(data["data"]["details"])
                logger.info(f"第{page}页采集完成")

        # 再统一遍历一下字典,新增一个字段 max_video_count
        list_data = [{**item, "max_video_count": 0,
                      "advertiser_id": advertiser_id} for item in list_data]
        with Mymongo() as mongo:
            mongo.delete_and_insert("素材列表", list_data, advertiser_id)
        return list_data
